home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / pascal / tptc17sc.zip / TPCSCAN.INC < prev    next >
Text File  |  1988-03-26  |  20KB  |  834 lines

  1.  
  2. (*
  3.  * TPTC - Turbo Pascal to C translator
  4.  *
  5.  * (C) 1988 Samuel H. Smith (rev. 13-Feb-88)
  6.  *
  7.  *)
  8.  
  9.  
  10. (********************************************************************)
  11. (*
  12.  * lexical scanner
  13.  *
  14.  *)
  15.  
  16. function numlit(n: integer): anystring;
  17. var
  18.    lit: string[6];
  19.    
  20.    {convert an integer into a c style numeric character literal}
  21.    function digit(n: integer): char;
  22.       (* convert an integer into a hex digit *)
  23.    begin
  24.       n := n and 15;
  25.       if n > 9 then n := n + 7;
  26.       digit := chr( n + ord('0') );
  27.    end;
  28.  
  29. begin
  30.    lit := '''\?''';
  31.  
  32.    case n of
  33.      $07:   lit[3] := 'a';
  34.      $08:   lit[3] := 'b';
  35.      $09:   lit[3] := 't';
  36.      $0a:   lit[3] := 'n';
  37.      $0b:   lit[3] := 'v';
  38.      $0c:   lit[3] := 'f';
  39.      $0d:   lit[3] := 'r';
  40.  
  41.      32..126,128..254:
  42.             lit := ''''+chr(n)+'''';
  43.  
  44.      else   begin
  45.                lit := '''\x??''';
  46.                lit[4] := digit(n shr 4);
  47.                lit[5] := digit(n);
  48.             end;
  49.    end;
  50.  
  51.    numlit := lit;
  52.    toktype := chars;
  53. end;
  54.  
  55.  
  56. (********************************************************************)
  57. procedure getchar;
  58.    {consume the current char and get the next one}
  59. var
  60.    stack: char;
  61. begin
  62.    if ofs(stack) < minstack then
  63.       fatal('Out of stack space');
  64.  
  65.    while (srclevel > 0) and eof(srcfd[srclevel]) do
  66.    begin
  67.       if not linestart then putline;
  68.       putln('/* TPTC: end of '+srcfiles[srclevel]+' */');
  69.       
  70.       if debug then writeln;
  71.       writeln(^M,srcfiles[srclevel],'(',srclines[srclevel],')');
  72.       
  73.       close(srcfd[srclevel]);
  74.       freemem(inbuf[srclevel],inbufsiz);
  75.  
  76.       dec(srclevel);
  77.       statustime := 0;
  78.    end;
  79.     
  80.    if eof(srcfd[srclevel]) then
  81.       nextc := '.'
  82.    else
  83.       read(srcfd[srclevel], nextc);
  84.  
  85.    if nextc = ^J then
  86.    begin
  87.       inc(srclines[srclevel]);
  88.       inc(srctotal);
  89.       
  90.       mark_time(curtime);
  91.       if (curtime >= statustime) or debug then
  92.       begin
  93.          if debug then writeln;
  94.          write(^M,srcfiles[srclevel],'(',srclines[srclevel],')');
  95.          statustime := curtime+statrate;
  96.          abortcheck;
  97.       end;
  98.    end;
  99. end;
  100.  
  101.  
  102. (********************************************************************)
  103. function usec: char;
  104.    {use up the current character(return it) and get
  105.     the next one from the input stream}
  106. var
  107.    c: char;
  108. begin
  109.    c := nextc;
  110.    getchar;
  111.    usec := c;
  112. end;
  113.  
  114.  
  115. (********************************************************************)
  116. function newc(n: string40): string40;
  117.    {replace the current character with a different one and get the next
  118.     character from the input stream}
  119. var
  120.    c: char;
  121. begin
  122.    c := nextc;
  123.    getchar;
  124.    newc := n;
  125. end;
  126.  
  127.  
  128. (********************************************************************)
  129. procedure concat_tokens;
  130.    {concatenate the next token and the current token}
  131. var
  132.    cur: string;
  133. begin
  134.    cur := ltok;
  135.    ltok := nextc;
  136.    toktype := unknown;
  137.    scan_tok;
  138.  
  139.    ltok := copy(cur,1,length(cur)-1) + copy(ltok,2,255);
  140.    ltok[1] := '"';
  141.    ltok[length(ltok)] := '"';
  142.    toktype := strng;
  143. end;
  144.  
  145.  
  146. (********************************************************************)
  147. procedure scan_ident;
  148.    {scan an identifier; output is ltok; nextc is first character following
  149.     the identifier; toktype = identifier;  this is the protocol for all of
  150.     the scan_xxxx procedures in the lexical analyzer}
  151. begin
  152.  
  153.    toktype := unknown;
  154.    ltok := '';
  155.  
  156.    repeat
  157.       case nextc of
  158.          'A'..'Z':
  159.             begin
  160.                if map_lower then
  161.                   nextc := chr( ord(nextc)+32 );
  162.                ltok := ltok + nextc;
  163.                getchar;
  164.             end;
  165.  
  166.          'a'..'z', '0'..'9', '_','@':
  167.             ltok := ltok + usec;
  168.  
  169.          else
  170.             toktype := identifier;
  171.       end;
  172.  
  173.    until toktype = identifier;
  174. end;
  175.  
  176.  
  177.  
  178. (********************************************************************)
  179. procedure scan_preproc;
  180.    {scan a tshell preprocessor directive;  same syntax as C already}
  181. begin
  182.    puts('#');
  183.  
  184.    repeat
  185.       puts(nextc);
  186.       getchar;
  187.    until nextc = ^M;
  188.  
  189.    getchar;
  190.    putline;
  191.    toktype := unknown;
  192. end;
  193.  
  194.  
  195. (********************************************************************)
  196. procedure scan_number;
  197.    {scan a number;  this also processes #nnn character literals, which are
  198.     converted into octal character literals.  imbedded periods are processed,
  199.     and a special condition is noted for trailing periods.  this is needed
  200.     for scanning the ".." keyword when used after numbers.  an ungetchar
  201.     facility would be more general, but isn't needed anywhere else.
  202.     in pascal/mt+, #nnn is translated into nnnL }
  203. var
  204.    hasdot:  boolean;
  205.    charlit:   boolean;
  206.    islong:  boolean;
  207.  
  208. begin
  209.    hasdot := false;
  210.    islong := false;
  211.    charlit := false;
  212.    toktype := number;
  213.  
  214. (* check for preprocessor directives, character literals or long literals *)
  215.    if nextc = '#' then
  216.    begin
  217.       ltok := '';
  218.       if mt_plus then
  219.          islong := true
  220.       else
  221.          charlit := true;
  222.    end;
  223.  
  224.    getchar;
  225.  
  226. (* check for preprocessor directives *)
  227.    if tshell and charlit and (nextc >= 'a') and (nextc <= 'z') then
  228.       scan_preproc
  229.    else
  230.  
  231.    repeat
  232.       case nextc of
  233.          '$','0'..'9','a'..'f','A'..'F':
  234.             ltok := ltok + usec;
  235.  
  236.          '.':
  237.             if hasdot then
  238.             begin
  239.                if ltok[length(ltok)] = '.' then
  240.                begin
  241.                   ltok[0] := pred(ltok[0]);  {remove trailing ., part of ..}
  242.                   if charlit then
  243.                      ltok := numlit(atoi(ltok));
  244.                   extradot := true;
  245.                end;
  246.                exit;
  247.             end
  248.             else
  249.  
  250.             begin
  251.                hasdot := true;
  252.                ltok := ltok + usec;
  253.             end;
  254.  
  255.          else
  256.             begin
  257.                if charlit then
  258.                begin
  259.                   ltok := numlit(atoi(ltok));
  260.                   if (nextc = '''') or (nextc = '^') or (nextc = '#') then
  261.                      concat_tokens;
  262.                   exit;
  263.                end;
  264.                
  265.                if ltok[1] = '$' then
  266.                   ltok := '0x' + copy(ltok,2,99);
  267.                if islong then
  268.                   ltok := ltok + 'L';
  269.                exit;
  270.             end;
  271.       end;
  272.  
  273.    until true=false;
  274. end;
  275.  
  276.  
  277. (********************************************************************)
  278. procedure scan_hat;
  279.    {scan tokens starting with ^ - returns ^X as a character literal 
  280.     corresponding to the specified control character.  returns ^ident as
  281.     an identifier with the leading ^ intact.  also scans ^. and ^[.}
  282. var
  283.    c: char;
  284.  
  285. begin
  286.    getchar;
  287.  
  288.    if ((nextc = '.') or (nextc = '[')) and 
  289.       ((ptoktype = identifier) or (ptok = ']')) then
  290.    begin
  291.       ltok := '^' + usec;     {^. or ^[}
  292.       exit;
  293.    end;
  294.  
  295.    case nextc of
  296.       '@','['..'`':
  297.          ltok := usec;
  298.          
  299.       'A'..'Z','a'..'z':
  300.          begin
  301.             ltok := nextc;
  302.             scan_ident;
  303.          end;
  304.        else
  305.          exit;
  306.    end;
  307.  
  308.    if length(ltok) = 1 then      {^c = control char}
  309.    begin
  310.       ltok := numlit( ord(upcase(ltok[1])) - ord('@') );
  311.       if (nextc = '''') or (nextc = '^') or (nextc = '#') then
  312.          concat_tokens;
  313.    end
  314.    else
  315.       ltok := '^' + ltok;        {^ident = pointer to ident}
  316.  
  317. end;
  318.  
  319.  
  320. (********************************************************************)
  321. procedure scan_dot;
  322.    {scans tokens starting with "."; knows about the 'extra dot' condition
  323.     that comes up in number scanning.  returns a token of either '.' or '..'}
  324. begin
  325.    getchar;
  326.  
  327.    if (nextc = '.') or extradot then
  328.    begin
  329.       ltok := '..';
  330.       extradot := false;
  331.    end;
  332.  
  333.    if nextc = '.' then
  334.       getchar;
  335. end;
  336.  
  337.  
  338. (********************************************************************)
  339. procedure scan_string;
  340.    {scans a literal string.  processes imbedded quotes ala pascal.  translates
  341.     the s